// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "../zen.h"

#include <filesystem>

namespace zen {

/** Scrub storage
 */
class ScrubCommand : public StorageCommand
{
public:
	ScrubCommand();
	~ScrubCommand();

	virtual int				  Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
	virtual cxxopts::Options& Options() override { return m_Options; }

private:
	cxxopts::Options m_Options{"scrub", "Scrub zen storage"};
	std::string		 m_HostName;
	bool			 m_DryRun = false;
	bool			 m_NoGc	  = false;
	bool			 m_NoCas  = false;
};

/** Garbage collect storage
 */
class GcCommand : public StorageCommand
{
public:
	GcCommand();
	~GcCommand();

	virtual int				  Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
	virtual cxxopts::Options& Options() override { return m_Options; }

private:
	cxxopts::Options m_Options{"gc", "Garbage collect zen storage"};
	std::string		 m_HostName;
	bool			 m_SmallObjects{false};
	bool			 m_SkipCid{false};
	bool			 m_SkipDelete{false};
	uint64_t		 m_MaxCacheDuration{0};
	uint64_t		 m_DiskSizeSoftLimit{0};
	bool			 m_ForceUseGCV1{false};
	bool			 m_ForceUseGCV2{false};
	uint32_t		 m_CompactBlockThreshold = 90;
	bool			 m_Verbose{false};
	bool			 m_SingleThreaded{false};
};

class GcStatusCommand : public StorageCommand
{
public:
	GcStatusCommand();
	~GcStatusCommand();

	virtual int				  Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
	virtual cxxopts::Options& Options() override { return m_Options; }

private:
	cxxopts::Options m_Options{"gc-status", "Garbage collect zen storage status check"};
	std::string		 m_HostName;
	bool			 m_Details = false;
};

class GcStopCommand : public StorageCommand
{
public:
	GcStopCommand();
	~GcStopCommand();

	virtual int				  Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
	virtual cxxopts::Options& Options() override { return m_Options; }

private:
	cxxopts::Options m_Options{"gc-stop", "Request cancel of running garbage collection in zen storage"};
	std::string		 m_HostName;
};

////////////////////////////////////////////

class JobCommand : public ZenCmdBase
{
public:
	JobCommand();
	~JobCommand();

	virtual int				  Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
	virtual cxxopts::Options& Options() override { return m_Options; }

private:
	cxxopts::Options m_Options{"jobs", "Show/cancel zen background jobs"};
	std::string		 m_HostName;
	std::uint64_t	 m_JobId  = 0;
	bool			 m_Cancel = 0;
};

////////////////////////////////////////////

class LoggingCommand : public ZenCmdBase
{
public:
	LoggingCommand();
	~LoggingCommand();

	virtual int				  Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
	virtual cxxopts::Options& Options() override { return m_Options; }

private:
	cxxopts::Options m_Options{"logs", "Show/control zen logging"};
	std::string		 m_HostName;
	std::string		 m_CacheWriteLog;
	std::string		 m_CacheAccessLog;
	std::string		 m_SetLogLevel;
	std::string		 m_ServerLogTarget;
	std::string		 m_CacheLogTarget;
	std::string		 m_HttpLogTarget;
};

/** Flush storage
 */
class FlushCommand : public StorageCommand
{
public:
	FlushCommand();
	~FlushCommand();

	virtual int				  Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
	virtual cxxopts::Options& Options() override { return m_Options; }

private:
	cxxopts::Options m_Options{"flush", "Flush zen storage"};
	std::string		 m_HostName;
};

/** Copy state
 */
class CopyStateCommand : public StorageCommand
{
public:
	CopyStateCommand();
	~CopyStateCommand();

	virtual int				  Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
	virtual cxxopts::Options& Options() override { return m_Options; }

private:
	cxxopts::Options	  m_Options{"copy-state", "Copy zen server disk state"};
	std::filesystem::path m_DataPath;
	std::filesystem::path m_TargetPath;
	bool				  m_SkipLogs;
};

}  // namespace zen
